home *** CD-ROM | disk | FTP | other *** search
- (*----------------------------------------------------------------------*)
- (* Display_ZIP_Contents --- Display contents of ZIP file *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Display_ZIP_Contents( ZIPFileName : AnyStr );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Display_ZIP_Contents *)
- (* *)
- (* Purpose: Displays contents of a ZIP file *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Display_ZIP_Contents( ZIPFileName : AnyStr ); *)
- (* *)
- (* ZIPFileName --- name of ZIP file whose contents are to be *)
- (* listed. *)
- (* *)
- (* Calls: *)
- (* *)
- (* Aside from internal subroutines, these routines are required: *)
- (* *)
- (* Get_Unix_Date --- convert Unix date to string *)
- (* Open_File --- open a file *)
- (* Close_File --- close a file *)
- (* Entry_Matches --- Perform wildcard match *)
- (* Display_Page_Titles *)
- (* --- Display titles at top of page *)
- (* DUPL --- Duplicate a character into a string *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- (*----------------------------------------------------------------------*)
- (* Map of ZIP file entry headers *)
- (*----------------------------------------------------------------------*)
-
- CONST
- ZIP_Central_Header_Signature = $02014B50;
- ZIP_Local_Header_Signature = $04034B50;
- ZIP_End_Central_Dir_Signature = $06054B50;
-
- Central_Dir_Found = 5;
-
- TYPE
- (* Structure of a local file header *)
- ZIP_Local_Header_Type =
- RECORD
- Signature : LONGINT (* Header signature *);
- Version : WORD (* Vers. needed to extract *);
- BitFlag : WORD (* General flags *);
- CompressionMethod : WORD (* Compression type used *);
- FileTime : WORD (* File creation time *);
- FileDate : WORD (* File creation date *);
- CRC32 : LONGINT (* 32-bit CRC of file *);
- CompressedSize : LONGINT (* Compressed size of file *);
- UnCompressedSize : LONGINT (* Original size of file *);
- FileNameLength : WORD (* Length of file name *);
- ExtraFieldLength : WORD (* Length of extra stuff *);
- END;
-
- (* Structure of the central *)
- (* directory record *)
- ZIP_Central_Header_Type =
- RECORD
- Signature : LONGINT (* Header signature *);
- VersionMadeBy : WORD (* System id/program vers. *);
- VersionNeeded : WORD (* Vers. needed to extract *);
- BitFlag : WORD (* General flags *);
- CompressionMethod : WORD (* Compression type used *);
- FileTime : WORD (* File creation time *);
- FileDate : WORD (* File creation date *);
- CRC32 : LONGINT (* 32-bit CRC of file *);
- CompressedSize : LONGINT (* Compressed size of file *);
- UnCompressedSize : LONGINT (* Original size of file *);
- FileNameLength : WORD (* Length of file name *);
- ExtraFieldLength : WORD (* Length of extra stuff *);
- CommentFieldLength : WORD (* Length of comments *);
- DiskStartNumber : WORD (* Disk # file starts on *);
- InternalAttributes : WORD (* Text/non-text flags *);
- ExternalAttributes : LONGINT (* File system attributes *);
- LocalHeaderOffset : LONGINT (* Where local hdr starts *);
- END;
-
- VAR
- ZIPFile : FILE (* ZIP file to be read *);
-
- ZIP_Entry : ZIP_Central_Header_Type (* Central header *);
-
- ZIP_Pos : LONGINT (* Current byte offset in ZIP file *);
- Bytes_Read : INTEGER (* # bytes read from ZIP file file *);
- Ierr : INTEGER (* Error flag *);
- File_Name : AnyStr (* File name of entry in ZIP file *);
-
- (*----------------------------------------------------------------------*)
- (* Get_Next_ZIP_Local_Header --- Get next local header in ZIP file *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Get_Next_ZIP_Local_Header( VAR ZIP_Local_Header :
- ZIP_Local_Header_Type;
- VAR Error : INTEGER ) : BOOLEAN;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Get_Next_ZIP_Local_Header *)
- (* *)
- (* Purpose: Gets next local header record in ZIP file *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* OK := Get_Next_ZIP_Local_Header( VAR ZIP_Local_Header: *)
- (* ZIP_Local_Header_Type; *)
- (* VAR Error : INTEGER ) : *)
- (* BOOLEAN; *)
- (* *)
- (* ZIP_Local_Header --- Local header data *)
- (* Error --- Error flag *)
- (* OK --- TRUE if header successfully found *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Get_Next_ZIP_Local_Header *)
-
- (* Assume no error to start *)
- Error := 0;
- (* Position file *)
- Seek( ZIPFile , ZIP_Pos );
- (* Read in the file header entry. *)
-
- IF ( IOResult <> 0 ) THEN
- Error := Format_Error
-
- ELSE
- BEGIN
-
- BlockRead( ZIPFile, ZIP_Local_Header, SIZEOF( ZIP_Local_Header ),
- Bytes_Read );
-
- (* If wrong size read, or header marker *)
- (* byte is incorrect, report ZIP file *)
- (* format error. *)
-
- IF ( ( IOResult <> 0 ) OR
- ( Bytes_Read < SIZEOF( ZIP_Local_Header_Type ) ) ) THEN
- Error := Format_Error
- ELSE
- (* Check for a legitimate header type *)
-
- IF ( ZIP_Local_Header.Signature = ZIP_Local_Header_Signature ) THEN
- BEGIN (* Local header -- skip it and associated data *)
-
- ZIP_Pos := ZIP_Pos + ZIP_Local_Header.FileNameLength +
- ZIP_Local_Header.ExtraFieldLength +
- ZIP_Local_Header.CompressedSize +
- SIZEOF( Zip_Local_Header_Type );
- END
-
- ELSE IF ( ZIP_Local_Header.Signature = ZIP_Central_Header_Signature ) THEN
- BEGIN (* Central header -- we want this *)
-
- Error := Central_Dir_Found;
-
- END
-
- ELSE IF ( ZIP_Local_Header.Signature = ZIP_End_Central_Dir_Signature ) THEN
- Error := End_Of_File;
-
- END;
- (* Report success/failure to calling *)
- (* routine. *)
-
- Get_Next_ZIP_Local_Header := ( Error = 0 );
-
- END (* Get_Next_ZIP_Local_Header *);
-
- (*----------------------------------------------------------------------*)
- (* Get_Next_ZIP_Entry --- Get next header entry in ZIP file *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Get_Next_ZIP_Entry( VAR ZIP_Entry : ZIP_Central_Header_Type;
- VAR FileName : AnyStr;
- VAR Error : INTEGER ) : BOOLEAN;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Get_Next_ZIP_Entry *)
- (* *)
- (* Purpose: Gets header information for next file in ZIP file *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* OK := Get_Next_ZIP_Entry( VAR ZIP_Entry : *)
- (* ZIP_Central_Header_Type; *)
- (* VAR FileName : AnyStr; *)
- (* VAR Error : INTEGER ) : BOOLEAN; *)
- (* *)
- (* ZIP_Entry --- Header data for next file in ZIP file *)
- (* FileName --- File name for this entry *)
- (* Error --- Error flag *)
- (* OK --- TRUE if header successfully found, else FALSE *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- L : INTEGER;
- L_Get : INTEGER;
- L_Got : INTEGER;
-
- BEGIN (* Get_Next_ZIP_Entry *)
- (* Assume no error to start *)
- Error := 0;
- (* Position file *)
- Seek( ZIPFile , ZIP_Pos );
- (* Read in the file header entry. *)
-
- IF ( IOResult <> 0 ) THEN
- Error := Format_Error
-
- ELSE
- BEGIN
-
- BlockRead( ZIPFile, ZIP_Entry, SIZEOF( ZIP_Central_Header_Type ),
- Bytes_Read );
-
- (* If wrong size read, or header marker *)
- (* byte is incorrect, report ZIP file *)
- (* format error. *)
-
- IF ( IOResult <> 0 ) THEN
- Error := Format_Error
- ELSE IF ( Bytes_Read < SIZEOF( ZIP_Central_Header_Type ) ) THEN
- BEGIN
- (* Check for end of directory *)
-
- IF ( ZIP_Entry.Signature = ZIP_End_Central_Dir_Signature ) THEN
- Error := End_Of_File
- ELSE
- Error := Format_Error;
-
- END
- ELSE
- (* Check for a legitimate header type *)
-
- IF ( ZIP_Entry.Signature = ZIP_Central_Header_Signature ) THEN
- BEGIN (* Central header -- we want this *)
-
- (* Pick up file name length. *)
- (* Only first 255 chars retrieved. *)
-
- L := ZIP_Entry.FileNameLength;
-
- IF ( L > 255 ) THEN
- L_Get := 255
- ELSE
- L_Get := L;
-
- (* Read file name characters. *)
-
- BlockRead( ZIPFile, FileName[ 1 ], L_Get, L_Got );
-
- (* Check for I/O error *)
-
- IF ( ( IOResult <> 0 ) OR ( L_Get<> L_Got ) ) THEN
- Error := Format_Error
- ELSE
- BEGIN
- (* Position to next header *)
-
- ZIP_Pos := ZIP_Pos + ZIP_Entry.ExtraFieldLength +
- ZIP_Entry.CommentFieldLength +
- ZIP_Entry.FileNameLength +
- SIZEOF( Zip_Central_Header_Type );
-
- (* Set length of file name *)
-
- FileName[ 0 ] := CHR( L_Got );
-
- END;
-
- END
- (* Check for end of directory *)
-
- ELSE IF ( ZIP_Entry.Signature = ZIP_End_Central_Dir_Signature ) THEN
- Error := End_Of_File
-
- (* Anything else is bogus *)
- ELSE
- Error := Format_Error;
-
- END;
-
- Get_Next_ZIP_Entry := ( Error = 0 );
-
- END (* Get_Next_ZIP_Entry *);
-
- (*----------------------------------------------------------------------*)
- (* Find_ZIP_Central_Directory --- Find central ZIP file directory *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Find_ZIP_Central_Directory( VAR Error : INTEGER ) : BOOLEAN;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Find_ZIP_Central_Directory *)
- (* *)
- (* Purpose: Finds central ZIP file directory *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* OK := Find_ZIP_Central_Directory( VAR Error : INTEGER ) : *)
- (* BOOLEAN; *)
- (* *)
- (* Error --- Error flag *)
- (* OK --- TRUE if header successfully found, else FALSE *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- ZIP_Local_Hdr : ZIP_Local_Header_Type (* Local header *);
-
- BEGIN (* Find_ZIP_Central_Directory *)
-
- (* Assume no error to start *)
- Error := 0;
- (* Start at beginning of file. *)
- ZIP_Pos := 0;
- (* Begin loop over local headers. *)
-
- (* Report success/failure to calling *)
- (* routine. *)
-
- WHILE ( Get_Next_ZIP_Local_Header( ZIP_Local_Hdr , Error ) ) DO;
-
- Find_ZIP_Central_Directory := ( Error = Central_Dir_Found );
-
- END (* Find_ZIP_Central_Directory *);
-
- (*----------------------------------------------------------------------*)
- (* Display_ZIP_Entry --- Display ZIP file file entry info *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Display_ZIP_Entry( ZIP_Entry : ZIP_Central_Header_Type ;
- File_Name : AnyStr );
-
- VAR
- FName : AnyStr;
- TimeDate : LONGINT;
- TimeDateW : ARRAY[1..2] OF WORD ABSOLUTE TimeDate;
- DirS : DirStr;
- FExt : ExtStr;
-
- BEGIN (* Display_ZIP_Entry *)
-
- WITH ZIP_Entry DO
- BEGIN
- (* Pick up short file name. *)
-
- FSplit( File_Name, DirS, FName, FExt );
-
- FName := FName + FExt;
-
- (* See if this file matches the *)
- (* entry spec wildcard. Exit if *)
- (* not. *)
- IF Use_Entry_Spec THEN
- IF ( NOT Entry_Matches( FName ) ) THEN
- EXIT;
- (* Get date and time of creation *)
-
- TimeDateW[ 1 ] := FileTime;
- TimeDateW[ 2 ] := FileDate;
-
- (* Display long file name if requested *)
- (* and if not the same as the short *)
- (* name. *)
-
- IF Show_Long_File_Names THEN
- IF ( FName = File_Name ) THEN
- File_Name := '';
-
- (* Display this entry's information *)
-
- Display_One_Entry( FName, UnCompressedSize, TimeDate, ZIPFileName,
- Current_Subdirectory, File_Name );
-
- END;
-
- END (* Display_ZIP_Entry *);
-
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Display_ZIP_Contents *)
- (* Open ZIP file and initialize *)
- (* contents display. *)
-
- IF Start_Contents_Listing( ' ZIP file: ',
- Current_Subdirectory + ZIPFileName, ZIPFile,
- ZIP_Pos, Ierr ) THEN
- BEGIN
- (* Skip to central directory in ZIP file *)
-
- IF Find_ZIP_Central_Directory( Ierr ) THEN
-
- (* Loop over entries *)
-
- WHILE ( Get_Next_ZIP_Entry( ZIP_Entry , File_Name , Ierr ) ) DO
- Display_ZIP_Entry( ZIP_Entry , File_Name )
-
- ELSE
- BEGIN
- Display_Error( 'Failed to find central ZIP directory' );
- Ierr := End_Of_File;
- END;
- (* Close ZIP file file *)
-
- End_Contents_Listing( ZIPFile , Ierr );
-
- END;
-
- END (* Display_ZIP_Contents *);
-